/**
 * @file    heat_mng.c
 * @brief   热管理
 * @author  Liuwei
 * @version 1.0.1
 * @date    2023-07-10
 * 
 * @copyright Copyright (c) 2023 JBD-Energy Storage Technology Co. LTD
 * 
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version   <th>Author   <th>Description
 * <tr><td>2023-07-10 <td>1.0.1     <td>Liuwei   <td>首次创建
 * </table>
 */

/* includes ------------------------------------------------------------------*/
#include "heat_mng.h"
#include "var_mng.h"
#include "param_mng.h"
#include "If_do.h"
#include "sample.h"
#include "diagnosis.h"
/* macro/define --------------------------------------------------------------*/
#define HOT_TRY_TIMES          (1800000)
#define START_DELAY_CNT        (2000)   
#define HOT_RECV_DLY           (30000)
/* typedef -------------------------------------------------------------------*/

/* local functions -----------------------------------------------------------*/

/* static variables ----------------------------------------------------------*/
static uint8_t heat_state = 0;
static uint8_t feng_state = 0;
static uint16_t start_hot_cnt = 0;
static uint16_t stop_hot_cnt = 0;
static uint32_t hot_try_cnt = 0;
static uint8_t hot_start_state = 0;
static uint16_t start_feng_cnt = 0;
static uint16_t stop_feng_cnt = 0;
static uint32_t feng_try_cnt = 0;
static uint8_t feng_start_state = 0;

/* global variables ----------------------------------------------------------*/

/** ------------------------------------------------------------------------- *
  *                             Global function
 ** ------------------------------------------------------------------------- */
/**
 * @brief 热管理初始化
 */
void heat_mng_init(void)
{
    heat_state = 0;
    feng_state = 0;
	
    If_do_set_output(DO_HOT_CTRL , DO_OUT_OFF);
}

/**
 * @brief 热管理进程
 */
void heat_mng_process(uint16_t cycle)
{
    float now_low_temp = 0;
    float now_max_temp = 0;
	uint16_t func_cfg = 0;
	uint16_t feng_cfg = 0;
	float start_temp = 0;
	float stop_temp = 0;
	float smp_curr = 0;
    now_low_temp = var_get_data(VAR_ID_MIN_TEMP_VAL)* 0.1 - 50;
    now_max_temp = var_get_data(VAR_ID_MAX_TEMP_VAL) * 0.1 - 50;
	
	start_temp = param_get_data(PAR_ID_HOT_START_TEMP) * 0.1 - 50;
	stop_temp = param_get_data(PAR_ID_HOT_STOP_TEMP) * 0.1 - 50;
	smp_curr = var_get_data(VAR_ID_BUS_CURR) * VAR_CURR_FACTOR - VAR_CURR_OFFSET;
	/*加热管理进程*/
	param_get_2bits_val(PAR_ID_FUNC_CFG ,FUNC_HOT_POS , &func_cfg); 
	if((PARAM_FUNC_CFG_EN == func_cfg)&&(feng_start_state == 0))
	{	
	
		if(0 == heat_state)
		{
			hot_start_state = 1;
			/* 发生充电低温保护 或 检测到充电电流,温度低于加热温度，启动加热*/
			if((now_low_temp < start_temp)
			   &&(var_get_data(VAR_ID_CURR_DR) == CURR_DR_CHG)
			   &&(smp_curr > 5)
		       &&(diag_get_prp(PRP_ID_OTE) == 0)
			   &&(now_max_temp < 25)) // 最高温度低于45℃
			{				
				start_hot_cnt += cycle;
				if(start_hot_cnt >= START_DELAY_CNT)
				{
					heat_state = 1;
					hot_start_state = 1;
					If_do_set_output(DO_HOT_CTRL , DO_OUT_ON);			
				}
			}
			else
			{
				start_hot_cnt = 0;
			}
			
			if(diag_get_prp(PRP_ID_UTC) == 1 && (diag_get_prp(PRP_ID_OTE) == 0) && (now_max_temp < 25))
			{
				heat_state = 1;
				hot_start_state = 1;
				If_do_set_output(DO_HOT_CTRL , DO_OUT_ON);
			}
			
			
			if(heat_state == 0)
			{
				if(If_do_get_out_state(DO_HOT_CTRL) == DO_OUT_ON)
				{
					If_do_set_output(DO_HOT_CTRL , DO_OUT_OFF);
				}
			}
			
		    hot_try_cnt = 0;
		}
		else
		{
			/** 温度高于加热停止温度 **/
			if((stop_temp <= now_low_temp) || (now_max_temp  > 25))
			{
				heat_state = 0;
				hot_start_state = 0;
				If_do_set_output(DO_HOT_CTRL , DO_OUT_OFF);
			}
			
			/** 检测到有放电电流持续30S **/
			if((var_get_data(VAR_ID_CURR_DR) == CURR_DR_DSG))
			{
				stop_hot_cnt += cycle;
				if(stop_hot_cnt >= HOT_RECV_DLY)
				{
					heat_state = 0;
					hot_start_state = 0;
					If_do_set_output(DO_HOT_CTRL , DO_OUT_OFF);
				}
			}
			else
			{
				stop_hot_cnt = 0;
			}
			
			/** 定时尝试恢复 */
			hot_try_cnt += cycle;
			if(hot_try_cnt >= HOT_TRY_TIMES)
			{
				diag_set_prp(PRP_ID_UTC , 0);
				hot_try_cnt = 0;
			}
			// 如果发生环境高温或充电高温保护，则关闭加热
			if(diag_get_prp(PRP_ID_OTE) || diag_get_prp(PRP_ID_OTC))
			{
				hot_try_cnt = 0;
				heat_state = 0;
				hot_start_state = 0;
			}
			
			if(heat_state == 1) // 如果加热MOS有打开 重新打开一次
			{
				if(If_do_get_out_state(DO_HOT_CTRL) == DO_OUT_OFF)
				{
					If_do_set_output(DO_HOT_CTRL , DO_OUT_ON);
				}
			}
		}
	}
	else
	{	
		heat_state = 0;
		hot_start_state = 0;
		start_hot_cnt = 0;
	}
/*风扇管理进程*/	
	param_get_2bits_val(PAR_ID_FUNC_CFG ,FUNC_FENG_POS , &feng_cfg); 
    if((PARAM_FUNC_CFG_EN == feng_cfg)&&(hot_start_state == 0))
	{		
		if(0 == feng_state)
		{
			feng_start_state = 1;
			/* 发生充电低温保护 或 检测到充电电流,温度低于加热温度，启动加热*/
			if((now_max_temp > start_temp)
		       &&(diag_get_prp(PRP_ID_OTE) == 0)
			   &&(now_max_temp > 25)) // 最高温度低于45℃
			{

				start_feng_cnt += cycle;
				if(start_feng_cnt >= START_DELAY_CNT)
				{
					feng_state = 1;
					feng_start_state = 1;
					If_do_set_output(DO_HOT_CTRL , DO_OUT_ON);			
				}
			}
			else
			{
				start_feng_cnt = 0;
			}
			
			if(diag_get_alarm(ALM_ID_OTC) || diag_get_alarm(ALM_ID_OTD)
				||diag_get_prp(PRP_ID_OTD)||diag_get_prp(PRP_ID_OTC)
			    ||diag_get_prp(PRP_ID_OTM)||diag_get_prp(PRP_ID_OTE))
			{
				if(diag_get_prp(PRP_ID_UTE) == 0) 
				{
				feng_state = 1;
				feng_start_state = 1;
				If_do_set_output(DO_HOT_CTRL , DO_OUT_ON);
				}
			}
			
			if(feng_state == 0)
			{
				if(If_do_get_out_state(DO_HOT_CTRL) == DO_OUT_ON)
				{
					If_do_set_output(DO_HOT_CTRL , DO_OUT_OFF);
				}
			}
			
		    feng_try_cnt = 0;
		}
		else
		{
			/** 最高温度低于风扇停止开启温度 **/
			if(stop_temp >= now_max_temp)
			{
				feng_state = 0;
				feng_start_state = 0;
				If_do_set_output(DO_HOT_CTRL , DO_OUT_OFF);
			}
			if((diag_get_prp(PRP_ID_BUV))||diag_get_prp(PRP_ID_CUV))
			{
				feng_state = 0;
				feng_start_state = 0;
				if(If_do_get_out_state(DO_HOT_CTRL) == DO_OUT_ON)
				{
					If_do_set_output(DO_HOT_CTRL , DO_OUT_OFF);
				}		
			}		
			else
			{
				stop_feng_cnt = 0;
			}
			
			/** 定时尝试恢复 */
			feng_try_cnt += cycle;
			if(feng_try_cnt >= HOT_TRY_TIMES)
			{
				diag_set_prp(PRP_ID_OTC , 0);
				diag_set_prp(PRP_ID_OTD , 0);
				feng_try_cnt = 0;
			}
			// 如果发生环境高温或充电高温保护，则关闭加热
			if(diag_get_prp(PRP_ID_UTE) || diag_get_prp(PRP_ID_UTC))
			{
				feng_try_cnt = 0;
				feng_state = 0;
				feng_start_state = 0;
			}
			
			if(feng_state == 1) // 如果加热MOS有打开 重新打开一次
			{
				if(If_do_get_out_state(DO_HOT_CTRL) == DO_OUT_OFF)
				{
					If_do_set_output(DO_HOT_CTRL , DO_OUT_ON);
				}
			}
		}
	}
	else
	{
		feng_state = 0;
		feng_start_state = 0;
		start_feng_cnt = 0;
	}	
	if((PARAM_FUNC_CFG_EN == feng_cfg)&&(PARAM_FUNC_CFG_EN == func_cfg))
	{
		if(If_do_get_out_state(DO_HOT_CTRL) == DO_OUT_ON)
		{
			If_do_set_output(DO_HOT_CTRL , DO_OUT_OFF);
		}			
	}	

	
	var_set_data(VAR_ID_HEAT_STATE , feng_state);
}
/** ------------------------------------------------------------------------- *
  *                              Local function
 ** ------------------------------------------------------------------------- */
 
/********** Copyright (c) 2023 JBD-Energy Storage Technology Co. LTD *********/
